package com.dunshan.order.config;


import com.dunshan.order.redb.RedisSelectSupport;
import com.dunshan.order.redb.SelectableRedisTemplate;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.MDC;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;

/**
 * @author .dunshan
 * @program: dunshan-pef
 * @description: 数据上下文
 * @date 2021-10-05 20:48:52
 */
@Log4j2
@Component
@Aspect
public class AopSwitchAspect {

    @Value("${spring.redis.master.database}")
    private int defaultDataBase;

    @Value("${spring.redis.shadow.database}")
    private int shadowDataBase;


    /**
     * 拦截入口下所有的 public方法
     */
    @Pointcut("execution(public * com.dunshan.order.controller..*(..))")
    public void pointCutAround() {
    }

    /**
     * 拦截处理
     *
     * @param point 信息
     * @return point
     */
    @Before(value = "pointCutAround()")
    public void around(JoinPoint point) {
        AppContext context = AppContext.getContext();
        String flag = context.getFlag();
        log.info("这里: " + flag);
        if (StringUtils.isNotEmpty(flag) && flag.equals(DataSourceNames.HEAD)) {
            MDC.put("dunshan", "shadow");
            DynamicDataSource.setDataSource(DataSourceNames.SHADOW);
        } else {
            MDC.put("dunshan", "produce");
            DynamicDataSource.setDataSource(DataSourceNames.MASTER);
        }
    }

    /**
     * @param point
     * @throws Throwable
     */
    @Around(value = "pointCutAround()")
    @ConditionalOnBean(SelectableRedisTemplate.class)
    public Object configRedis(ProceedingJoinPoint point) throws Throwable {
        AppContext context = AppContext.getContext();
        String flag = context.getFlag();
        int db = defaultDataBase;
        try {
            if (flag != null && flag.equals(DataSourceNames.HEAD)) {
                db = shadowDataBase;
                log.info("redis 压测流量：" + db);
            } else {
                db = defaultDataBase;
                log.info("redis 正常流量: " + db);
            }
            RedisSelectSupport.select(db);
            return point.proceed();
        } finally {
            RedisSelectSupport.select(defaultDataBase);
            log.debug("redis switch {} to {}", defaultDataBase, db);
        }
    }


}
